package com.globallogic.oopbasics.competence.io;

import java.io.*;
import java.util.Scanner;

import com.globallogic.oopbasics.competence.exception.LevelException;

public abstract class ReadWithScanner {

	private final File fFile;

	/**
	 * Constructor
	 * 
	 * @param aFileName
	 *            full name of an existing, readable file.
	 * @throws FileNotFoundException
	 * @throws LevelException 
	 */
	public ReadWithScanner(String aFileName) throws FileNotFoundException,
			IllegalArgumentException, LevelException {
		init();
		fFile = new File(aFileName);
		processLineByLine();
	}

	/** Template method that calls {@link #processLine(String)}. 
	 * @throws LevelException */
	public final void processLineByLine() throws FileNotFoundException,
			IllegalArgumentException, LevelException {
		// Note that FileReader is used, not File, since File is not Closeable
		Scanner scanner = new Scanner(new FileReader(fFile));
		try {
			if (!scanner.hasNextLine()) {
				throw new IllegalArgumentException(
						"Empty file. Unable to process.");
			} else {
				while (scanner.hasNextLine()) {
					processLine(scanner.nextLine());
				}
			}
		} finally {
			// ensure the underlying stream is always closed
			// this only has any effect if the item passed to the Scanner
			// constructor implements Closeable (which it does in this case).
			scanner.close();
		}
	}

	/**
	 * Overridable method for processing lines in different ways.
	 * @throws LevelException 
	 */
	protected void processLine(String aLine) throws LevelException {
	}

	protected void init() {
	}
}
